#ifndef _VIEW_MANAGER_H_
#define _VIEW_MANAGER_H_

#include"GraphicData.h"
#include"GraphicsSettings.h"
#include"Vec3D.h"
#include"View.h"
#include"Object.h"
#include"Legend.h"
#include"RContext.h"
#include"../utils/fv_dictstr.h"
#include"../utils/fv_timer.h"
#include<vector>
#include<string>

namespace FemViewer
{
	class Tile;
	class GraphicsSettings;
	//class mfvWindow;

	class ViewManager
	{
		friend ViewManager& ViewManagerInst(void);
		friend class RContext;
		/* Ctr & Dtr
		**/
		ViewManager(int destWidth = 512, int destHeight = 512);
	public:
		~ViewManager();
		/* Initialize member must be called after OpenGL init
		**/
		void Init(int destWidth, int destHeight);
		/* Reset ViewManger to its defaults
		**/
		void Reset();
		/* Adds new view
		**/	
		void AddView(const View& pView);
		/* Generates status message on screen
		**/ 
		void AddStatusMsg(const std::string& msg);
		/* Clear all messages from window
		**/
		void ClearStatusMsg();
		/* Called every time if need to redraw content
		**/
		void Display(const Tile& pTile);

		void DisplayCallback();

		GraphicData& GetGraphicData();

		GraphicsSettings* GetSettings();

		bool IdleCallback();

		bool KeyboardCallback(unsigned char key);

		bool KeyboardSpecialCallback(int key);

		bool MenuCallback(const int& iEvent);

		bool MouseButtonCallback(int button,
                             int state,
                             unsigned keystate,
                             int x,
                             int y);

		bool MouseMotionCallback(int pX, int pY);

		void ReshapeCallback(int pWidth, int pHeight);

		void InitGL(int width,int height);

		void SetTitle(const std::string* pTitle);

		void SetLegend(const Legend& pLegend);
		Legend& GetLegend() { return legend; }

		enum ViewResetMode { ViewReset_None, ViewReset_BBoxOnly, ViewReset_FullReset };
  
		void SetViewResetMode(ViewResetMode pMode) { eViewResetMode = pMode; }

		GLuint CreateVBO(const void* data, int dataSize, GLenum target, GLenum usage);

		bool IsVBOSuported() const { return vboSupported; }

		bool IsVBOUsed() const { return vboUsed; }

		//RContext GetCurrentRCoontext();
	private:
		enum MouseMode {
			MOUSE_NONE,
			MOUSE_ROTATE,
			MOUSE_TRANSLATE,
			MOUSE_ZOOM
		};

		Object oAxes;
		View currentView;
		GraphicData aGraphicData;
		Legend legend;
		Object oGrid;
		//Object oCube;
		Object oLegend;
		int iLastMouseX;
		int iLastMouseY;
		MouseMode eMoveMode;
		bool bNewViewAdded;
		ViewResetMode eViewResetMode;
		std::vector<std::string> vecStatusMsgs;
		const std::string* sTitle;
		GraphicsSettings UserSettings;
		int iViewIndex;
		std::vector<View> vecViews;
		int iWndWidth;
		int iWndHeight;
		bool vboSupported;
		bool vboUsed;
		bool bUseExternalModule;
		unsigned int uFrameCount;
		bool bMeasurePerformance;
		fv_timer cTimer;
		double dLastTime;

		void DrawAxes();
		void DrawGrid();
		void DrawLegend(const Tile& pTile);
		void DrawCubeSides();
		void DrawFPS();
		void DrawMouseMovementIndicators();
		void DrawTextLayer(const Tile& pTile);
		void Render(const Tile& pTile);
		void ResetCamera();
		void SetupLighting();
		void CreateCubeGrid();
	    /* Block use these
		**/
		ViewManager(const ViewManager& rhs);
		ViewManager& operator=(const ViewManager& rhs);
	};

	extern ViewManager& ViewManagerInst(void);

} // end namespace FemViewer

#endif /* _VIEW_MANAGER_H_ */
